﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using ElasticReflection;

namespace ElasticPropertyPath.Core
{
    public class PropertyPathExtractor
    {

        public static string PropertyPath<T>(Expression<Func<T>> expression)
        {
            return Resolve(expression.Body);
        }


        public static string Resolve(Expression ex)
        {
            dynamic expression = ex;

            if (ex.NodeType == ExpressionType.MemberAccess)
            {
                if (expression.Member.Attributes.ToString().Contains("Static")) throw new Exception("Static member access is not allowed;");

                if (expression.Expression != null && expression.Expression.NodeType != ExpressionType.Constant)
                {
                    return Resolve(expression.Expression) + "." + expression.Member.Name;
                }
                return expression.Member.Name;
            }
            if (ex.NodeType == ExpressionType.Convert)
            {
                return Resolve(expression.Operand);
            }
            if (ex.NodeType == ExpressionType.ArrayIndex)
            {
                string array = Resolve(expression.Left);
                string index = Resolve(expression.Right);

                return array + "[" + index + "]";
            }
            if (ex.NodeType == ExpressionType.Constant)
                return expression.Value.ToString();

            throw new Exception("Not supported expression NodeType:" + ex.NodeType);
        }

        public static T PropertyValue<T>(Expression<Func<T>> expression)
        {
            return expression.Compile()();
        }

        public static Type PropertyType<T>(Expression<Func<T>> expression)
        {
            return typeof(T);
        }


        
    }
}
